<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// $Id$

/**
 +------------------------------------------------------------------------------
 * Sqlite数据库驱动类
 +------------------------------------------------------------------------------
 * @category   Think
 * @package  Think
 * @subpackage  Db
 * @author    liu21st <liu21st@gmail.com>
 * @version   $Id$
 +------------------------------------------------------------------------------
 */
class DbSqlite extends Db
{//类定义开始

/**
 +----------------------------------------------------------
 * 架构函数 读取数据库配置信息
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @param array $config 数据库配置数组
 +----------------------------------------------------------
 */
public function __construct($config=''){
	if ( !extension_loaded('sqlite') ) {
		throw_exception(L('_NOT_SUPPERT_').':sqlite');
	}
	if(!empty($config)) {
		if(!isset($config['mode'])) {
			$config['mode']	=	0666;
		}
		$this->config	=	$config;
	}
}

/**
 +----------------------------------------------------------
 * 连接数据库方法
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
public function connect($config='',$linkNum=0) {
	if ( !isset($this->linkID[$linkNum]) ) {
		if(empty($config))	$config	=	$this->config;
		$conn = $this->pconnect ? 'sqlite_popen':'sqlite_open';
		$this->linkID[$linkNum] = $conn($config['database'],$config['mode']);
		if ( !$this->linkID[$linkNum]) {
			throw_exception(sqlite_error_string());
		}
		// 标记连接成功
		$this->connected	=	true;
		//注销数据库安全信息
		if(1 != C('DB_DEPLOY_TYPE')) unset($this->config);
	}
	return $this->linkID[$linkNum];
}

/**
 +----------------------------------------------------------
 * 释放查询结果
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 */
public function free() {
	$this->queryID = 0;
}

/**
 +----------------------------------------------------------
 * 执行查询 返回数据集
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @param string $str  sql指令
 +----------------------------------------------------------
 * @return mixed
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
public function query($str) {
	$this->initConnect(false);
	if ( !$this->_linkID ) return false;
	$this->queryStr = $str;
	//释放前次的查询结果
	if ( $this->queryID ) $this->free();
	N('db_query',1);
	// 记录开始执行时间
	G('queryStartTime');
	$this->queryID = sqlite_query($this->_linkID,$str);
	$this->debug();
	if ( false === $this->queryID ) {
		$this->error();
		return false;
	} else {
		$this->numRows = sqlite_num_rows($this->queryID);
		return $this->getAll();
	}
}

/**
 +----------------------------------------------------------
 * 执行语句
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @param string $str  sql指令
 +----------------------------------------------------------
 * @return integer
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
public function execute($str) {
	$this->initConnect(true);
	if ( !$this->_linkID ) return false;
	$this->queryStr = $str;
	//释放前次的查询结果
	if ( $this->queryID ) $this->free();
	N('db_write',1);
	// 记录开始执行时间
	G('queryStartTime');
	$result	=	sqlite_exec($this->_linkID,$str);
	$this->debug();
	if ( false === $result ) {
		$this->error();
		return false;
	} else {
		$this->numRows = sqlite_changes($this->_linkID);
		$this->lastInsID = sqlite_last_insert_rowid($this->_linkID);
		return $this->numRows;
	}
}

/**
 +----------------------------------------------------------
 * 启动事务
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @return void
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
public function startTrans() {
	$this->initConnect(true);
	if ( !$this->_linkID ) return false;
	//数据rollback 支持
	if ($this->transTimes == 0) {
		sqlite_query($this->_linkID,'BEGIN TRANSACTION');
	}
	$this->transTimes++;
	return ;
}

/**
 +----------------------------------------------------------
 * 用于非自动提交状态下面的查询提交
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @return boolen
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
public function commit()
{
	if ($this->transTimes > 0) {
		$result = sqlite_query($this->_linkID,'COMMIT TRANSACTION');
		if(!$result){
			throw_exception($this->error());
		}
		$this->transTimes = 0;
	}
	return true;
}

/**
 +----------------------------------------------------------
 * 事务回滚
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @return boolen
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
public function rollback()
{
	if ($this->transTimes > 0) {
		$result = sqlite_query($this->_linkID,'ROLLBACK TRANSACTION');
		if(!$result){
			throw_exception($this->error());
		}
		$this->transTimes = 0;
	}
	return true;
}

/**
 +----------------------------------------------------------
 * 获得所有的查询数据
 +----------------------------------------------------------
 * @access private
 +----------------------------------------------------------
 * @return array
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
private function getAll() {
	//返回数据集
	$result = array();
	if($this->numRows >0) {
		for($i=0;$i<$this->numRows ;$i++ ){
			// 返回数组集
			$result[$i] = sqlite_fetch_array($this->queryID,SQLITE_ASSOC);
		}
		sqlite_seek($this->queryID,0);
	}
	return $result;
}

/**
 +----------------------------------------------------------
 * 取得数据表的字段信息
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @return array
 +----------------------------------------------------------
 */
public function getFields($tableName) {
	$result =   $this->query('PRAGMA table_info( '.$tableName.' )');
	$info   =   array();
	if($result){
		foreach ($result as $key => $val) {
			$info[$val['Field']] = array(
                    'name'    => $val['Field'],
                    'type'    => $val['Type'],
                    'notnull' => (bool) ($val['Null'] === ''), // not null is empty, null is yes
                    'default' => $val['Default'],
                    'primary' => (strtolower($val['Key']) == 'pri'),
                    'autoinc' => (strtolower($val['Extra']) == 'auto_increment'),
			);
		}
	}
	return $info;
}

/**
 +----------------------------------------------------------
 * 取得数据库的表信息
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @return array
 +----------------------------------------------------------
 */
public function getTables($dbName='') {
	$result =   $this->query("SELECT name FROM sqlite_master WHERE type='table' "
	. "UNION ALL SELECT name FROM sqlite_temp_master "
	. "WHERE type='table' ORDER BY name");
	$info   =   array();
	foreach ($result as $key => $val) {
		$info[$key] = current($val);
	}
	return $info;
}

/**
 +----------------------------------------------------------
 * 关闭数据库
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @throws ThinkExecption
 +----------------------------------------------------------
 */
public function close() {
	if ($this->_linkID && !sqlite_close($this->_linkID)){
		throw_exception($this->error());
	}
	$this->_linkID = 0;
}

/**
 +----------------------------------------------------------
 * 数据库错误信息
 * 并显示当前的SQL语句
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @return string
 +----------------------------------------------------------
 */
public function error() {
	$this->error = sqlite_error_string(sqlite_last_error($this->_linkID));
	if($this->debug && '' != $this->queryStr){
		$this->error .= "\n [ SQL语句 ] : ".$this->queryStr;
	}
	return $this->error;
}

/**
 +----------------------------------------------------------
 * SQL指令安全过滤
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @param string $str  SQL指令
 +----------------------------------------------------------
 * @return string
 +----------------------------------------------------------
 */
public function escape_string($str) {
	return sqlite_escape_string($str);
}

/**
 +----------------------------------------------------------
 * limit
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 * @return string
 +----------------------------------------------------------
 */
public function parseLimit($limit) {
	$limitStr    = '';
	if(!empty($limit)) {
		$limit  =   explode(',',$limit);
		if(count($limit)>1) {
			$limitStr .= ' LIMIT '.$limit[1].' OFFSET '.$limit[0].' ';
		}else{
			$limitStr .= ' LIMIT '.$limit[0].' ';
		}
	}
	return $limitStr;
}

/**
 +----------------------------------------------------------
 * 析构方法
 +----------------------------------------------------------
 * @access public
 +----------------------------------------------------------
 */
public function __destruct()
{
	// 关闭连接
	$this->close();
}
}//类定义结束
?>